package com.rear.components;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.rear.utils.PropertyUtils;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;


/**
 * 打印件生成下载组件
 * @author wjz
 *
 */
public class PrintComponent implements ServletContextListener{
	private final static Logger logger = Logger.getLogger(PrintComponent.class);
	private static String directory;
	PrintComponent(){
		directory=PropertyUtils.getValue("image.file.path") +File.separator+ "cache";
		File file = new File(directory);
		if (!file.exists()) {
			file.mkdirs();
		}
	}
	
	@Autowired
	public static FreeMarkerConfigurer freeMarkerConfigurer;

	@Autowired
	public static Configuration freeMarkerConfiguration;

	@SuppressWarnings("static-access")
	public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {
		this.freeMarkerConfigurer = freeMarkerConfigurer;
	}

	@SuppressWarnings("static-access")
	public void setFreeMarkerConfiguration(Configuration freeMarkerConfiguration) {
		this.freeMarkerConfiguration = freeMarkerConfiguration;
	}
	
	/**
	 * 关闭是销毁文件夹
	 */
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		try {
			
			boolean flag = false;
			File file = new File(directory);  
			// 判断目录或文件是否存在  
			if (!file.exists()) {  // 不存在返回 
				logger.info("不存在"+directory);
			} else {  
				// 判断是否为文件  
				if (file.isFile()) {  // 为文件时调用删除文件方法  
					flag=deleteFile(directory);  
				} else {  // 为目录时调用删除目录方法  
					flag=deleteDirectory(directory);  
				}  
			}  
			logger.info(directory+"删除--"+flag);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 启动时建立文件夹
	 */
	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		File outFile = new File(directory,"cache.txt");
		try {
			logger.info("启动建立文件夹");
			if(outFile.exists()) {
				// 文件已经存在，输出文件的相关信息
				logger.info(outFile.getAbsolutePath());
				logger.info(outFile.getName());
				logger.info(outFile.length());
			} else {
				//  先创建文件所在的目录
				outFile.getParentFile().mkdirs();
				try {
					// 创建新文件
					outFile.createNewFile();
				} catch (IOException e) {
					logger.error("创建新文件时出现了错误。。。");
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	
	/** 
	 * 删除目录（文件夹）以及目录下的文件 
	 * @param   sPath 被删除目录的文件路径 
	 * @return  目录删除成功返回true，否则返回false 
	 */  
	static public boolean deleteDirectory(String sPath) {  
		 boolean flag = true;  
		 File dirFile = new File(sPath);  
		try {
			 //如果sPath不以文件分隔符结尾，自动添加文件分隔符  
		    if (!sPath.endsWith(File.separator)) {  
		        sPath = sPath + File.separator;  
		    }  
		    
		    //如果dir对应的文件不存在，或者不是一个目录，则退出  
		    if (!dirFile.exists() || !dirFile.isDirectory()) {  
		        return flag=false;  
		    }  
		   
		    //删除文件夹下的所有文件(包括子目录)  
		    File[] files = dirFile.listFiles();  
		    for (int i = 0; i < files.length; i++) {  
		        //删除子文件  
		        if (files[i].isFile()) {  
		            flag = deleteFile(files[i].getAbsolutePath());  
		            if (!flag) break;  
		        } //删除子目录  
		        else {  
		            flag = deleteDirectory(files[i].getAbsolutePath());  
		            if (!flag) break;  
		        }  
		    }  
		    if (!flag) return flag=false;  
		    //删除当前目录  
		    if (dirFile.delete()) {  
		        return flag=true;  
		    } else {  
		        return flag=false;  
		    }  
		} catch (Exception e) {
			logger.error("e:{}",e);
		}
		return flag;
	   
	} 
	/** 
	 * 删除单个文件 
	 * @param   sPath    被删除文件的文件名 
	 * @return 单个文件删除成功返回true，否则返回false 
	 */  
	static public boolean deleteFile(String sPath) {
		boolean flag = false;  
		try {
			File file = new File(sPath);  
		    // 路径为文件且不为空则进行删除  
		    if (file.isFile() && file.exists()) {  
		        file.delete();  
		        flag = true;  
		    }  
		} catch (Exception e) {
			logger.error("e:{}",e);
		}
	    return flag;  
	}  

	
	
	

	/**
	 * 打印件生成
	 * @param <T>
	 * @param list 循环的list
	 * @param listName list的名称
	 * @param fileHead 文件的开头
	 * @param templateName 模板名称
	 * @return
	 * @throws IOException
	 */
	public static <T> String createFile(List<T> list,String listName,String fileHead,String templateName) throws IOException {
		Map<String,Object> dataMap=new HashMap<String,Object>();    
        dataMap.put(listName, list);
        @SuppressWarnings("deprecation")
		Configuration configuration = new Configuration();
        configuration.setClassForTemplateLoading(PrintComponent.class, "/template"); 
        FileOutputStream fos=null;
        Template template=null; 
        Writer out = null;
        String fileName = fileHead+System.currentTimeMillis()+".xls";
        try {
        	template =freeMarkerConfigurer.getConfiguration().getTemplate(templateName);
        
        	logger.info("directory:"+directory);
       
        	logger.info("fileName:"+fileName);
 
        	File outFile = new File(directory,fileName);
        
        	fos=new FileOutputStream(outFile);
       
        	out = new BufferedWriter(new OutputStreamWriter(fos,"UTF-8"));
        
        	template.process(dataMap, out);    
        } catch (TemplateException e) {    
        	e.printStackTrace();   }
        catch (IOException e) {    
        	e.printStackTrace();    
        }finally {
        	if(null!=out){
        		out.flush();
        		out.close();
        	}
        	if(null!=fos){
        		fos.close();
        	}
        }
        return fileName;
	}
	
	
	/**
	 * 打印件下载
	 * @param fileName 文件名称
	 * @param out 
	 * @param resp
	 * @throws Exception
	 */
	public static void downDocument(
			String fileName,
			OutputStream out, 
			HttpServletResponse resp)throws Exception {
		fileName = fileName.isEmpty() ? "" : fileName;
		
		FileInputStream in = null;
		File file = null;
		try {
			resp.reset();
			// 设定输出格式
			resp.setContentType("application/mx-word;charset=utf-8");
			resp.setCharacterEncoding("UTF-8");
			resp.setHeader("Content-Disposition", "attachment; filename="
					+ URLEncoder.encode(fileName, "UTF-8"));
			file = new File(directory+ File.separatorChar + fileName);
			in = new FileInputStream(file);
			
			byte[] buf = new byte[8192];
			int len = -1;
			while ((len = in.read(buf)) != -1) {
				out.write(buf, 0, len);
			}

		} catch (Exception e) {
			logger.error("", e);
		} finally {
			if (out != null) {
				try {
					out.close();
					out = null;
				} catch (IOException e) {
					 e.printStackTrace();
				}
			}
			if (in != null) {
				try {
					in.close();
					in = null;
				} catch (IOException e) {
					 e.printStackTrace();
				}
			}
			if (file != null && file.exists()) {
				file.deleteOnExit();
			}
		}
	}
	
}
